/**
 * Copyright (C), 2021-2023, 四信物联网有限公司
 * FileName: BDicpMessageHandler
 * Author:   Chapin
 * Date:     2023/10/20 17:53
 * Description: ICP消息处理
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.fourfaith.iot.beidou.handler;

import com.fourfaith.common.pojo.ResultDto;
import com.fourfaith.iot.beidou.decodec.BeiDouContants;
import com.fourfaith.iot.beidou.message.inbound.BDtciMessage;
import com.fourfaith.iot.device.cloud.access.dubbo.pojo.param.BeiDouParam;
import com.fourfaith.iot.device.cloud.access.dubbo.service.IBeidouDubboService;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 〈TCI消息处理〉
 * @author Chapin
 * @create 2023/10/20
 * @since 1.0.0
 */
@Slf4j
public class BDtciMessageHandler extends SimpleChannelInboundHandler<BDtciMessage> {

    private final IBeidouDubboService beidouDubboService;

    // 消息缓存,去重
    private final ConcurrentHashMap<String,Long> messageMap = new ConcurrentHashMap();

    public BDtciMessageHandler(IBeidouDubboService beidouDubboService) {
        this.beidouDubboService = beidouDubboService;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, BDtciMessage msg) throws Exception {
        // 清理过期的消息
        cleanExpiredMessages();
        if (messageMap.containsKey(msg.getSenderNumber() + msg.getTime())) {
            log.info("数据重复，不处理：{}", msg);
            return;
        } else {
            messageMap.put(msg.getSenderNumber() + msg.getTime(), System.currentTimeMillis());
            BeiDouParam beiDouParam = new BeiDouParam();
            beiDouParam.setVersion(BeiDouContants.BEI_DOU3);
            beiDouParam.setFunctionCode(msg.getCommand());
            String data = msg.getData();
            if (StringUtils.isNotBlank(data)) {
                // 混发编码类型
                if ("3".equals(msg.getEncodingType())) {
                    if (data.startsWith("A4")) {
                        data = data.substring(2);
                    } else {
                        log.error("混发编码类型，数据格式错误：{}", data);
                        return;
                    }
                }
                beiDouParam.setMessageContext(data);
                // 水文协议
                if (data.toUpperCase(Locale.ROOT).startsWith("7E7E")) {
                    beiDouParam.setProtocol(BeiDouContants.PROTOCOL_HYDROLOGICAL);
                }
                // 广播协议
                else if (data.toUpperCase(Locale.ROOT).startsWith("7E") && data.toUpperCase(Locale.ROOT).endsWith("7E")) {
                    beiDouParam.setProtocol(BeiDouContants.PROTOCOL_BROADCASTL);
                }
            } else {
                log.error("数据为空");
                return;
            }
            beiDouParam.setReceivedId(msg.getAcceptorNumber());
            beiDouParam.setSendId(msg.getSenderNumber());
            try {
                ResultDto<Boolean> result = beidouDubboService.receive(beiDouParam);
                log.info("北斗消息推送服务器：{}", result);
            } catch (Exception e) {
                log.info("推送失败：{}", e.getMessage(), e);
            }
        }
    }

    /**
     * 清理过期的消息
     */
     private void cleanExpiredMessages(){
         messageMap.values().removeIf(timestamp -> System.currentTimeMillis() - timestamp > 60 * 1000);
     }

}